package IAPractica1;
import java.util.ArrayList;

import IA.Gasolina.CentrosDistribucion;
import IA.Gasolina.Gasolinera;
import IA.Gasolina.Gasolineras;

public class Representation {	
	
	/* Variables de classe */
	private static ArrayList<Integer> gasAsociada;
	private static ArrayList<Integer>	idAsociat;	
	private static CentrosDistribucion centros;
	private static Gasolineras gasolineras;
	private static int xMitja;
	private static int yMitja;
	private static int totalPet;
	
	/* Parametres de classe */
	private static int costeKm = 2;
	private static int nGas = 100;
	private static int nCent = 10;
	private static int seed1 = 1234;
	private static int seed2 = 1234;
	private static int mult = 1;		
	public static String SWAP = "Swap";	
	public static String ADD = "Add";	
	
	// Estado de cada centro (km actuales recorridos, viajes actuales hechos)
	//private ArrayList<Integer> assignacions;
	private  ArrayList<StateCentre> estado;
	
	
	/* parametres */
	
	Representation(int numGas, int numCentros, int mult, int seed1, int seed2, int costeKm) {	
		initialize(numGas,numCentros,mult,seed1,seed2,costeKm);			
	}	
	
	Representation(ArrayList<StateCentre> estado) {	
		this.estado = estado;
	}	
	
	public int getPeticionesTotales(){
		return totalPet;
	}
	
	@SuppressWarnings("unused")
	public void initialize(int nGas, int nCent, int mult, int seed1, int seed2, int costeKm){	
		
		this.nGas = nGas;
		this.nCent = nCent;
		this.mult = mult;
		this.seed1 = seed1;
		this.seed2 = seed2;
		this.costeKm = costeKm;
			
		gasolineras = new Gasolineras(nGas, seed1);
		centros = new CentrosDistribucion(nCent, mult, seed2);	
		estado = new ArrayList<StateCentre> ();
				
		// Estado de las restricciones de cada centro
		for (int i = 0; i < nCent*mult; i++){
			int x = centros.get(i).getCoordX();
			int y = centros.get(i).getCoordY();
			estado.add(new StateCentre(x,y));//,gasAsociada,gasolineras));			
		}
		
		// total de peticiones
		totalPet = 0;			 		
		for (int i = 0; i < gasolineras.size(); i++) {				
			totalPet += gasolineras.get(i).getPeticiones().size();			
		}	
		
		gasAsociada = new ArrayList<Integer>();
		idAsociat = new ArrayList<Integer>();
		
		Delivery entregaEstatica = new Delivery(gasAsociada,gasolineras);
		
		/*Asociamos peticiones totales con gasolineras y sus respeectivas peticiones*/
		//int actual = 0;
		
		int numPet;
		for(int i = 0; i < nGas; i++){
			Gasolinera g = gasolineras.get(i);
			numPet = (g.getPeticiones()).size();
			
			for (int j = 0; j < numPet; j++){
				
				//gasAsociada.set(actual+j, i);
				//idAsociat.set(actual+j, j);	
				gasAsociada.add(i);
				idAsociat.add(j);	
			}
			//actual += numPet;			
		}				

		/*Calculamos el punto medio de los centros*/
		xMitja = yMitja = 0;
		for (int i = 0; i < nCent*mult; ++i) { //para cada centro...
			xMitja += centros.get(i).getCoordX();
			yMitja += centros.get(i).getCoordY();
		}
		xMitja /= nCent;
		yMitja /= nCent;
	}
	
	
	public void setEstado(ArrayList<StateCentre> estado){
		this.estado = estado;		
	}
	
	public ArrayList<StateCentre> getEstado(){
		return estado;
	}
		
	
	public ArrayList<Integer> getGasAsociadas(){
		return gasAsociada;
	}
	
	
	public Gasolineras getGasolineras(){
		return gasolineras;
	}
	
	
	
	public CentrosDistribucion getCentrosDistribucion(){
		return centros;
	}
	
	
	public ArrayList<Integer> getIdAssociats(){
		return idAsociat;
	}
	
	public int getTotalKm(){
		int total = 0;
		for (int i = 0; i < estado.size(); i++)
			total += estado.get(i).getKm();
		
		return total;
	}

	public int getCoordXMitja() {
		return xMitja;
	}

	public int getCoordYMitja() {
		return yMitja;
	}
	
	public int getCosteKm() {
		return costeKm;
	}
	
	// deberia ser private para no confundirlo con un operador
	
	
	
	/*A la tarda les acabo/reviso*/
	
	public Representation copy(){
		ArrayList<StateCentre> estadoCopy = new ArrayList<StateCentre> ();
		for(int i = 0; i< nCent; ++i)
			estadoCopy.add(estado.get(i).copy());
		return new Representation(estadoCopy);
	}
	

	boolean swap(int idCentre1, int idEntrega1, int idPeticio1, int idCentre2, int idEntrega2, int idPeticio2){
					
		if(idCentre1 == -1) return estado.get(idCentre2).subsParada(idEntrega2,idPeticio2,idPeticio1);
		else if(idCentre2 ==-1) return estado.get(idCentre1).subsParada(idEntrega1,idPeticio1,idPeticio2);
		return ((estado.get(idCentre1).subsParada(idEntrega1,idPeticio1,idPeticio2))&&(estado.get(idCentre2).subsParada(idEntrega2,idPeticio2,idPeticio1)));
	}	
	

	public ArrayList<Pair> getNotFull() {
		ArrayList<Pair> list = new ArrayList<Pair>();
		for(int i = 0; i < nCent; ++i)
			estado.get(i).afegirEntreguesNotFull(list,i);
		return  list;
	}



	public ArrayList<Integer> GetPeticionsNoServides() {
		ArrayList<Integer> PeticionsNoServides = new ArrayList<Integer>();	
		ArrayList<Integer> assignacions = getAssignacions();
		for(int i = 0; i<totalPet; ++i)
			if(assignacions.get(i)==-1) PeticionsNoServides.add(i);
		return PeticionsNoServides;
	}
	
	public ArrayList<Integer> getAssignacions(){
		
		 ArrayList<Integer> assignacions = new ArrayList<Integer>();
		 for(int i = 0; i < totalPet; ++i)
			 assignacions.add(-1);
		 for(int i = 0; i < nCent; ++i)
			estado.get(i).validarPeticions(assignacions,i);
		 
		 return assignacions;
	}	
	

	public ArrayList<Integer> getidEntregues() {
		ArrayList<Integer> idEntregues = new ArrayList<Integer>();
		for(int i =0; i<totalPet; ++i)
			idEntregues.add(-1);
		for(int i =0; i<nCent; ++i)
			estado.get(i).getidEntregues(idEntregues);
		return idEntregues;
	}
	
	public void delete (int idCentre, int idEntrega,int idPeticio){		
		(estado.get(idCentre)).deleteParada(idEntrega,idPeticio);
	}

	
	public boolean add (int idCentre, int idEntrega,int idPeticio){		
		return (estado.get(idCentre)).addParada(idEntrega,idPeticio);
	}
}




